<script setup>
import _ from 'lodash';
import {computed, nextTick, onMounted, reactive, ref, toRefs, watch} from "vue";
import {$pageUtils} from '@jzl/utils'

// import {ResizeObserver} from 'vue3-resize'
// import { VueDraggableNext } from 'vue-draggable-next'
import {useBuilder} from "./hooks/useBuilder.js";

import BuilderHeader from './builder-header.vue'
import BuilderNodes from './builder-nodes.vue'
import BuilderItem from "./builder-item.vue"
import BuilderMask from './builder-mask.vue'

defineOptions({
  name: 'JzlPageBuilderScreen'
})

const emit = defineEmits(['ready'])
const props = defineProps({
  inPageId: {
    type: [Number, String],
    default: null
  },
  pageId: {
    type: [Number, String],
    default: null
  },
  appId: {
    type: [Number, String],
    default: null
  },
  /*isH5: {
    type: Boolean,
    default: true
  },*/
  inPageType: {
    type: [Number, String],
    default: 1
  }
})

const {
  scale,
  containerLeft,
  containerTop
} = toRefs(reactive({
  pageType: 1,
  scale: 0.5,
  containerLeft: 0,
  containerTop: 0
}))

const appViewBodyRef = ref(null)

const {
  loading,
  currentPage,
  isRouterEnter,
  ready,
  items,
  pageTheme,
  initElemNodes,

  pageType,
  isH5,
  className,
  dataset,
  // pageWidth,
  currentItem,
  currentItemElCode,
  hoverItemElCode,
  handleSelectItem,
  handleItemEnter,
  handleItemLeave,
  handleItemStateChange,
  isEditItem,
  lowcode,
  elemNodes,

  handleShowCompMarket,
  handlePageSetting,
  handleLowcodeChange,
  // handlePageResize,

  currentItems,
  currentNode,
  pinMenu,
  pinProp,

  handleHoverElenode,
  handleMouseLeaveElenode,
  handleSelectElenode,
  handleMenuClick,
  handleShowCloudCompWin,
  handleDropDone,
  handlePinPropChange,
  handlePinMenuChange,

  pageAddShow,
  pageForm,
  pageAdd,

  handleClickDesignBody,
  submit
} = useBuilder(props, emit, {})

const pageStyle = computed(() => {
  let style = $pageUtils.getStyle(currentPage.value, "style");
  return _.assign({}, style, { width: `${ pageWidth.value }px`, height: `${ pageHeight.value }px` /*scale: scale.value, left: `${containerLeft.value}px`, top: `${containerTop.value}px`*/})
})

const pageWidth = computed(() => {
  return _.get(currentPage.value, 'style._ss.width') || 1920;
})

const pageHeight = computed(() => {
  return _.get(currentPage.value, 'style._ss.height') || 1080;
})

const initScale = () => {
  let $el = appViewBodyRef.value;

  if(!$el) return;
  let rect = $el.getBoundingClientRect();
  let width = rect.width - 20;
  let height = rect.height - 20;
  let iScale = calculateScale(width, height);

  console.log(`---- initScale ... width: ${ width }, height: ${ height }, iScale: ${ iScale }`)

  containerTop.value = (rect.height - pageHeight.value * iScale) / 2;
  containerLeft.value = (rect.width - pageWidth.value * iScale) / 2;
  scale.value = iScale;
}

const calculateScale = (targetWidth, targetHeight) => {
  // 计算宽度和高度的缩放比
  const widthScale = targetWidth / pageWidth.value;
  const heightScale = targetHeight / pageHeight.value;
  // 选择较小的缩放比，以确保元素能完全放入目标区域
  const scale = Math.min(widthScale, heightScale);
  return scale;
}

const handlePageResize = () => {
  nextTick(() => {
    initScale();
  });
}

onMounted(() => {
  nextTick(() => {
    initScale();
  })
})

watch(() => [currentPage.value.style?._ss?.width, currentPage.value.style?._ss?.height], () => {
  initScale()
})
watch(() => appViewBodyRef.value, () => {
  initScale()
})
</script>

<template>
  <div
    class="builder-page-container"
    :class="className"
    v-loading="loading"
  >
    <BuilderHeader
      :current-page="currentPage"
      :is-router-enter="isRouterEnter"
      :page-type="pageType"
      v-bind="$attrs"
      @showCompMarket="handleShowCompMarket"
      @showPageSetting="handlePageSetting"
      @lowcode-change="handleLowcodeChange"
      @submit="submit"
    />
    <div
      class="page-builder-container"
      ref="bbody"
      v-if="ready"
    >
      <div
        class="page-builder-body"
        :class="{ 'pin-prop': pinProp, 'pin-menu': pinMenu }"
        ref="jbody"
      >
        <div
          class="ele-design-body "
          ref="bformbody"
          @click="handleClickDesignBody"
        >
          <div
            class="ele-design-body-items"
            ref="appViewBodyRef"
          >
            <div
              class="jzl-page-body ele-design-body-items-drag jzl-page jzl-page-bs"
              :class="[{ 'empty': !items || items.length <= 0 }, pageTheme ]"
              :style="pageStyle"
              @mouseleave.stop="handleMouseLeaveElenode"
            >
              <BuilderMask
                :current-item="currentItem"
                :current-el-code="currentItemElCode"
                :hover-el-code="hoverItemElCode"
                :elem-nodes="elemNodes"
                :current-node="currentNode"
                :container="appViewBodyRef"
              />

              <template
                v-for="(item, index) in items"
                :key="item.page_item_code || index"
              >
                <BuilderItem
                  :item="item"
                  :is-h5="isH5"
                  :items="items"
                  :vars="dataset.state"
                  :index="index"
                  :page-width="pageWidth"
                  :current-item="currentItem"
                  @selectItem="handleSelectItem"
                  @itemEnter="handleItemEnter"
                  @itemLeave="handleItemLeave"
                  @itemStateChange="handleItemStateChange"
                />
              </template>
              <!--              <ResizeObserver @notify="handlePageResize"/>-->
            </div>
          </div>
        </div>

        <BuilderNodes
          v-if="ready"
          ref="builderNodes"
          :page-type="pageType"
          :items="items"
          :is-edit-item="isEditItem"
          :dataset="dataset"
          :lowcode="lowcode"
          :elem-nodes="elemNodes"
          :in-pin-menu="pinMenu"
          :current-item-el-code="currentItemElCode"
          :current-item="currentItem"
          :current-page="currentPage"
          :current-items="currentItems"
          :current-node="currentNode"
          :container="appViewBodyRef"
          @hoverElenode="handleHoverElenode"
          @selectElenode="handleSelectElenode"
          @selectItem="handleSelectItem"
          @create-page-item="handleMenuClick"
          @show-cloud-comps="handleShowCloudCompWin"
          @node-drop-done="handleDropDone"
          @pinPropChange="handlePinPropChange"
          @pinMenuChange="handlePinMenuChange"
        />
        <!--        @changeElemNodes="initElemNodes" @eleNodeTreeChange="initElemNodes"-->
      </div>
      <el-dialog
        title="新增页面"
        :visible.sync="pageAddShow"
        width="400px">
        <el-form
          :model="pageForm">
          <el-form-item
            label="页面名称"
            label-width="100">
            <el-input
              v-model="pageForm.name"
              autocomplete="off"
            />
          </el-form-item>
        </el-form>
        <div slot="footer" class="dialog-footer">
          <el-button @click="pageAddShow = false">取 消</el-button>
          <el-button type="primary" @click="pageAdd()">确 定</el-button>
        </div>
      </el-dialog>
    </div>
  </div>
</template>

<style lang="scss" scoped>
.page-builder-container .page-builder-body .ele-design-body .ele-design-body-items {
  overflow: auto;
}

.vue-grid-layout {
  min-height: 220px;
}
</style>
